/*
 * Copyright (c) 2025 Huawei Technologies Co., Ltd.
 * openUBMC is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *         http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

#include <mcpy/builtins/lambda.h>

namespace mcpy {

namespace detail {

// 填充默认值的辅助函数（避免模板代码膨胀）
mc::variants fill_defaults(
    const mc::variants& args,
    const mc::variants& defaults,
    size_t              first_default_index,
    size_t              total_param_count) {
    mc::variants full_args;
    full_args.reserve(total_param_count);

    for (size_t i = 0; i < total_param_count; ++i) {
        if (i < args.size()) {
            full_args.push_back(args[i]);
        } else {
            size_t default_idx = i - first_default_index;
            full_args.push_back(defaults[default_idx]);
        }
    }

    return full_args;
}

} // namespace detail

mc::variant lambda_extension_base::call(const mc::variants& args) {
    size_t min_args = this->get_min_arg_count();
    size_t max_args = this->get_arg_count();

    if (args.size() < min_args) {
        MC_THROW(mc::invalid_arg_exception,
                 "期望至少 {expected} 个参数，实际 {actual}",
                 ("expected", min_args)("actual", args.size()));
    }

    return this->call_impl(args);
}

std::string_view lambda_extension_base::get_type_name() const {
    return "lambda";
}

mc::extension_type_info lambda_extension_base::get_type_info() const {
    return mc::extension_type_info_traits<lambda_extension_base>::get();
}

bool lambda_extension_base::equals(const mc::variant_extension_base& other) const {
    return this == &other;
}

std::size_t lambda_extension_base::hash() const {
    return std::hash<const void*>{}(static_cast<const void*>(this));
}

mc::shared_ptr<mc::variant_extension_base> lambda_extension_base::copy() const {
    return nullptr;
}

mc::shared_ptr<mc::variant_extension_base> lambda_extension_base::deep_copy(
    mc::detail::copy_context* ctx) const {
    MC_UNUSED(ctx);
    return nullptr;
}

} // namespace mcpy
